//
//  HMStatusListViewModel.swift
//  HMWeiBo
//
//  Created by Apple on 16/7/31.
//  Copyright © 2016年 itheima. All rights reserved.
//

import UIKit
import SDWebImage

class HMStatusListViewModel: NSObject {

    // 定义一个属性,用于接收 字典转模型的数据
//    lazy var list: [HMStatusModel] = [HMStatusModel]()
    
    lazy var list: [HMHomeCellViewModel] = [HMHomeCellViewModel]()
    
    func loadData(since_id: Int,max_id: Int,success: ()->(),failed: ()->()){
        /*
        接下来就是数据缓存的逻辑! 注意: 每个公司和每个公司的缓存逻辑不一样,我们重点是给大家讲数据库的读取,并不是 缓存的逻辑
        
        1. 先读取数据库的数据
        2. 如果数据库里的数据不满足要求,就网络请求
        */
        
        readDBData(since_id, max_id: max_id) { (data) -> () in
            
            // 如果满足查询条件,data有值,
            // 否则没有值,没有值 进行网络请求
            
            if data.count > 0 {
                
                var temp = [HMHomeCellViewModel]()
                
                // 有满足的数据
                // 把满足的数据进行一个解析,然后进行回调
                // 2. 对数组进行遍历
                for status in data {
                    
                    let statusModel = HMStatusModel(dict: status)
                    
                    // 3. 把模型添加到数组里
                    //temp 是需要添加ViewModel
                    let viewModel = HMHomeCellViewModel()
                    
                    // 4.把model赋值给ViewModel
                    viewModel.statusModel = statusModel
                    
                    temp.append(viewModel)
                }
                
                
                if max_id > 0  {
                    // 到赋值的这里,我们需要判断一下,是否是 上拉加载更多
                    self.list = self.list + temp
                } else  {
                    // 5. 赋值
                    self.list = temp + self.list
                    
                }
                
                // 6.回调
                success()
                
            
                
                
            } else {
                
                // 网络请求
                self.netloadData(since_id, max_id: max_id, success: success, failed: failed)
            }
            
        }
        
    }
    
    
    func netloadData(since_id: Int,max_id: Int,success: ()->(),failed: ()->()){
        
        // 1. url
        let urlString = "https://api.weibo.com/2/statuses/home_timeline.json"
        
        // 2.拼接参数
        /*
        必选	类型及范围	说明
        access_token	true	string	采用OAuth授权方式为必填参数，OAuth授权后获得。
        since_id	false	int64	若指定此参数，则返回ID比since_id大的微博（即比since_id时间晚的微博），默认为0。
        max_id	false	int64	若指定此参数，则返回ID小于或等于max_id的微博，默认为0。
        */
        //        HMLoginViewModel.shareInstance.access_token
        
        guard let token = HMLoginViewModel.shareInstance.access_token else {
            
            return
        }
        
        let params = ["access_token": token,
            "since_id":since_id,
            "max_id":max_id]
        
       
        // 调试接口的时候,一定要打印一下参数
        printLog(params)
        
//        HMHTTPClient.request(.GET, URLString: urlString, parameters: params, success: { (jsonDict) -> () in
//            printLog(jsonDict)
//            }) { (error) -> () in
//                printLog(error)
//        }
        
        
        // 3.
        
        HMHTTPClient.shareInstance.request(.GET, URLString: urlString, parameters: params, progress: nil, success: { (_ , JSON) -> Void in
            
            printLog(JSON)
            // 对 JSON 进行数据的处理
            guard let json = JSON as? [String: AnyObject] else {
                
                return
            }
            
            // 0. 初始化一个数组
            var temp: [HMHomeCellViewModel] = [HMHomeCellViewModel]()
            
            // 创建一个调度组
            let group = dispatch_group_create()
            
            // 1. 获取到statues数组
            if let statuses = json["statuses"] as? [[String: AnyObject]] {
                
                // 在这里调用一个数据保存 -- 异步去保存数据
                self.saveWeiboData(statuses)
                
                // 2. 对数组进行遍历
                for status in statuses {
                    
                    let statusModel = HMStatusModel(dict: status)
                    
                    // 2.1 判断一下单张图片,然后下载单张图片
                    
                    // 注意事项: 转发微博的话,配图在转发的model
                    // 原创微博的配图为空 ? (转发微博的配图) : (原创微博的配图)
                    let pic_urls = statusModel.pic_urls == nil ? (statusModel.retweeted_status?.pic_urls):(statusModel.pic_urls)
                    
                    // 判断一个配图的个数:
                    // 1. pic_urls 变成非可选项
                    // 2. 再判断数量
                    if let pic_URLS = pic_urls where pic_URLS.count == 1 {
                        
                        // 当数组的图片 等于 1的时候,去下载单张图片
                        // 下载图片可以自己去实现,也可以借助于 SDWebImage
                        
                        guard  let urlString = pic_URLS.first?.thumbnail_pic else {
                            return
                        }
                        
                        dispatch_group_enter(group)
                        
                        let url = NSURL(string: urlString)!
                        //
                        SDWebImageManager.sharedManager().downloadImageWithURL(url, options: [], progress: nil, completed: { (image, error, _ , _ , _ ) -> Void in
                            print("单张图片下载完成")
                            dispatch_group_leave(group)
                        })
                        
                    }
                    
                    
                    
                    // 3. 把模型添加到数组里
                    //temp 是需要添加ViewModel
                    let viewModel = HMHomeCellViewModel()
                    
                    // 4.把model赋值给ViewModel
                    viewModel.statusModel = statusModel
                    
                    temp.append(viewModel)
                }
                
                
                if max_id > 0  {
                    // 到赋值的这里,我们需要判断一下,是否是 上拉加载更多
                    self.list = self.list + temp
                } else  {
                    // 5. 赋值
                    self.list = temp + self.list
                
                }
            }
           
            dispatch_group_notify(group, dispatch_get_main_queue(), { () -> Void in
                
                // 当所有的单张图片,下载完成之后, 会走这里
                // 单张图片都下载到本地了,再去刷新数据
                // 再去进行回调,
                success()
                
            })
           
            
            }) { (_ , error) -> Void in
                
                
               failed()
        }

        
    }

    
    //MARK:-- 数据的保存方法操作
    private func saveWeiboData(data: [[String: AnyObject]]){
        
        // 1. replace -- 替换
        let sql = "INSERT OR REPLACE INTO T_Status (status,statusId,userId) VALUES (?,?,?);"
        
        printLog(sql)
        
        // userId 我们可以用 access_token /uid
        guard let userId = HMLoginViewModel.shareInstance.model?.uid else {
            return
        }
        
        // 对数组进行遍历,一条微博一条微博的保存
        for weibo in data {
            
            let statusId = weibo["id"] as! Int
            
            // weibo 是字典类型,保存到数据库里之后,就是 string
            // 当我们再次读取的时候,不能把 读取出来的 sting转换成字典
            // 我们需要把 weibo 字典转换成 data ,再把data转换成一个String
            
            // throws
            
            let data = try! NSJSONSerialization.dataWithJSONObject(weibo, options: [])
            
            // 把data转换成String
            guard let str = String(data: data, encoding: NSUTF8StringEncoding) else {
                return
            }
            
            // 调用数据库保存的方法
            FMDBManager.shareInstance.queue.inDatabase({ (db) -> Void in
                if db.executeUpdate(sql, withArgumentsInArray: [str,statusId,userId]){
                    
                    printLog("插入成功")
                }
            })
            
        }
        
        
    }
    //MARK:-- 数据的读取操作
    func readDBData(since_id: Int,max_id: Int,finish: (data: [[String: AnyObject]])->() ){
        
        /*
        SELECT status,statusId FROM T_Status
        -- WHERE statusId > 4006963337444441  -- 大于微博id返回最新数据
        WHERE statudId < 4006963337444441 -- 小于微博id返回旧数据
        ORDER BY statusId DESC  -- 排序
        LIMIT 0,20; -- 返回20条微博
        */
        
        // 1. 先写sql
        var sql = "SELECT status FROM T_Status\n"
        
        if since_id > 0 {
            // 最新微博
            sql = sql + "WHERE statusId > \(since_id)\n"
        } else if max_id > 0{
            
            // 旧微博
            sql = sql + "WHERE statusId < \(max_id)\n"
        }
        
        sql = sql + "ORDER BY statusId DESC LIMIT 0,20;"
        
        printLog(sql)
        
        // 2. 执行sql语句
        
        var temp: [[String: AnyObject]] = [[String: AnyObject]]()
        
        FMDBManager.shareInstance.queue.inDatabase { (db) -> Void in
           let sets = db.executeQuery(sql, withArgumentsInArray: nil)
            
            while sets.next() {
                
                // 获取对应列的数据
                let status = sets.stringForColumn("status")
                // 微博数据是 String 
                // 保存的时候是 字典-> 二进制-> String
                
                // 把 sting转换成二进制
                guard let data = status.dataUsingEncoding(NSUTF8StringEncoding) else {
                    return
                }
                do {
                
                    // 把二进制转换成字典
                    // throws
                    let dict = try NSJSONSerialization.JSONObjectWithData(data, options: [])
                    
                    // 把字典添加到数组里
                    temp.append(dict as! [String : AnyObject])
                } catch { // 捕捉异常
                    // error 就是异常信息
                    printLog(error)
                    // 如果 try后边的语句出现异常就走 catch
                    
                    
                }
                
                
            }
        }
        
        
        // 进行回调
        finish(data: temp)
        
        
    }
    
    /* as
    throws 有三种请求
    try 默认 do{} catch{} -- 不会崩溃
    try? -- 可选项 -- 不会崩溃
    try! -- 强制解包 -- 有可能崩溃
    */
}
